package com.jweb.plugins.rpc.core;

import java.io.File;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jweb.framework.AppConstant;
import com.jweb.framework.core.CharSet;
import com.jweb.framework.core.ConfigHandle;
import com.jweb.plugins.rpc.Constant;
import com.jweb.plugins.rpc.annotation.RpcProvider;
import com.jweb.plugins.rpc.bean.Service;
import com.jweb.plugins.rpc.bean.ZNode;
import com.jweb.plugins.rpc.impl.AgreementFactory;
import com.jweb.plugins.rpc.impl.handler.ServiceType;

/**
 * 服务端发布服务
 * 
 * @author Yuanqy
 *
 */
public class RpcPublish {
	private static final Logger logger = LoggerFactory.getLogger(RpcPublish.class);
	private Map<String, Service> handler = new HashMap<String, Service>(); // 存放接口名与服务对象之间的映射关系
	private int port = ConfigHandle.getInt("rpc.server.port", 5120);
	private String host = AppConstant.CONFIG.LocalIP.getValue();

	public void create(Set<Class<?>> rpcServices) throws Exception {
		try {
			if (rpcServices.size() > 0) {
				// ==获取服务和实现类=============
				RpcProvider rpc = null;
				Service ser = null;
				Set<ServiceType> suport = new HashSet<ServiceType>();// 服务类型
				for (Class<?> cls : rpcServices) {
					rpc = cls.getAnnotation(RpcProvider.class);
					ser = new Service(cls.getAnnotation(RpcProvider.class).iface(), cls, rpc.serviceType(), rpc);
					handler.put(ser.getIface().getName()+File.separator+rpc.serviceType().getName(), ser);
					suport.add(rpc.serviceType());
				}
				// == 创建服务 ===================
				if (AgreementFactory.startServer(handler, host, port, suport)) {
					registerZKService();
				}
			}
		} catch (Exception e) {
			logger.error("RPC服务发布失败", e);
			throw e;
		}
	}

	private void registerZKService() {
		try {
			// == 注册服务节点 ====================
			if (ZkFactory.getZK() != null) {
				String node2 = Constant.PROVIDERS;
				Service ser = null;
				RpcProvider rpcp = null;
				for (Entry<String, Service> en : handler.entrySet()) {
					ser = en.getValue();
					rpcp = ser.getRpcProvider();
					String node1 = ser.getIface().getName();
					String node3 = URLEncoder.encode(new ZNode(host, port, 1, 100, rpcp.version(), "", ser.getServiceType()).toString(), CharSet.Default);
					ZkFactory.createPathLine(Constant.ZK_REGISTRY_PATH + "/" + node1 + "/" + node2 + "/" + node3); // 注册服务地址
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
